using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;

using Tino.Core;

namespace Tino
{
    public partial class TagsAdministrationForm : Form
    {
        TagsListItemsCollection deletedItems;
        TagsListItemsCollection addedItems;

        public TagsListItemsCollection DeletedItems
        {
            get { return deletedItems; }
        }

        public TagsListItemsCollection AddedItems
        {
            get { return addedItems; }
        }

        public TagsAdministrationForm()
        {
            InitializeComponent();

            deletedItems = new TagsListItemsCollection();
            addedItems = new TagsListItemsCollection();

            loadTags();

            // Final UI tasks
            addTagTextBox.Select();
        }

        /// <summary>
        /// Load all the existing Tags into the tagsList CheckedListBox
        /// </summary>
        void loadTags()
        {
            GetTagsCommand command = new GetTagsCommand(tagsList);
            command.Execute();
        }

        bool Commit()
        {
            TagElement tagElt = new TagElement();

            // Remove deleted items ...
            foreach (TagsListItem item in deletedItems)
            {
                Debug.WriteLine(string.Format("Deleting tag {0}", item.Name));
                tagElt.DeleteTag(item.ID);
            }

            // Add new ones
            foreach (TagsListItem item in addedItems)
            {
                int id = 0;
                try
                {
                    Debug.WriteLine(string.Format("Adding tag {0}", item.Name));
                    id = tagElt.AddTag(item.Name);
                    item.ID = id;
                }
                catch (Exception)
                {
                    MessageBox.Show(string.Format("Error saving tag {0}.", item.Name));
                    Debug.WriteLine(string.Format("Error saving tag {0}.", item.Name));
                    return false;
                }
            }

            return true;
        }

        void addItem(string tagName)
        {
            // Make sure it is not in the DeletedList - if so, take back the one from the bin
            for(int i = 0; i < deletedItems.Count; i++)
            {
                TagsListItem item = deletedItems[i];
                if (item.Name == tagName)
                {
                    tagsList.Items.Add(item);
                    deletedItems.RemoveAt(i);
                    return;
                }
            }
            
            // Make sure it does not already exists
            if (indexOf(tagName) > -1)
                return;
            
            // All conditions are ok, add the item
            TagsListItem newItem = new TagsListItem(-1, tagName);
            tagsList.Items.Add(newItem);          
            // Add it to the added list
            addedItems.Add(newItem);
        }

        int indexOf(string tagName)
        {
            for (int i = 0; i < tagsList.Items.Count; i++)
                if (((TagsListItem)tagsList.Items[i]).Name == tagName)
                    return i;

            return -1;
        }

        void deleteItem(TagsListItem item)
        {
            tagsList.Items.Remove(item);
            // Add it to the deleted list only if it's not an added item
            if (item.ID > -1)
                deletedItems.Add(item);

            // If the item was added before, then remove it from the AddedList
            if (item.ID == -1)
            {
                int idx = -1;
                for (int i = 0; i < addedItems.Count; i++)
                {
                    TagsListItem t = addedItems[i];
                    if (t.Name == item.Name)
                    {
                        idx = i;
                        break;
                    }
                }
                addedItems.RemoveAt(idx);
            }
        }

        #region Form event handlers

        void Form_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                DialogResult = DialogResult.Cancel;
                Close();
            }
        }

        void addTagTextBox_TextChanged(object sender, EventArgs e)
        {
            TextBox t = (TextBox)sender;
            addButton.Enabled = (t.Text != "");
        }

        void addTagTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                TextBox t = (TextBox)sender;
                if (t.Text != "")
                {
                    addItem(t.Text);
                    t.Text = "";
                }
            }
        }

        void addTagTextBox_Enter(object sender, EventArgs e)
        {
            tagsList.SelectedIndices.Clear();
        }

        void addButton_Click(object sender, EventArgs e)
        {
            if (addTagTextBox.Text != "")
            {
                addItem(addTagTextBox.Text);
                addTagTextBox.Text = "";
            }
        }

        void tagsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            delButton.Enabled = (tagsList.SelectedItems.Count > 0);
        }

        void delButton_Click(object sender, EventArgs e)
        {
            for (int i = tagsList.SelectedItems.Count - 1; i > -1; i--)
                deleteItem((TagsListItem)tagsList.SelectedItems[i]);
        }

        void okButton_Click(object sender, EventArgs e)
        {
            if (Commit())
            {
                DialogResult = DialogResult.OK;
                Close();
            }
        }

        void cancelButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        #endregion 
    }
}